
from __future__ import absolute_import
from __future__ import with_statement
__metaclass__ = type

import os
import sys

class colors:
    @staticmethod
    def capable():
        return (hasattr(sys.stderr, 'fileno') and
                   os.isatty(sys.stderr.fileno()))

    def random(self, text, choice=None):
        import random
        if not self.capable():
            return text
        if choice is None:
            choice = random.randint(0,10000)
        i = choice % 16
        func = self.codes.keys()[i]
        func = getattr(self, func)
        return func(text)

    normal = '\033[0m'

    esc = '\033[%sm'
    codes = dict([
        ("Black"       , "0;30"),
        ("Red"         , "0;31"),
        ("Green"       , "0;32"),
        ("Brown"       , "0;33"),
        ("Blue"        , "0;34"),
        ("Purple"      , "0;35"),
        ("Cyan"        , "0;36"),
        ("LightGray"   , "0;37"),
        ("DarkGray"    , "1;30"),
        ("LightRed"    , "1;31"),
        ("LightGreen"  , "1;32"),
        ("Yellow"      , "1;33"),
        ("LightBlue"   , "1;34"),
        ("LightPurple" , "1;35"),
        ("LightCyan"   , "1;36"),
        ("White"       , "1;37")
    ])


for name, value in colors.codes.items():
    def makefunc():
        esc = colors.esc % value
        def wrap(self, text):
            if self.capable():
                return "%s%s%s" % (esc, text, colors.normal)
            return text
        return wrap
    setattr(colors, name, makefunc())

colors = colors()


def get_ipython(locs):
    from IPython.Shell import IPShell
    shell = IPShell(user_ns=locs, argv=[])
    return shell.mainloop


def get_bpython(locs):
    from bpython.cli import main
    return lambda:main([], locs)


def get_builtin(locs):
    import code
    shell = code.InteractiveConsole(locals=locs)
    try:
        import readline
    except ImportError:
        pass
    return shell.interact


def get_shell(namespace):
    shell = None
    #mods = get_bpython, get_ipython
    mods = get_ipython,
    for f in mods:
        try:
            return f(namespace)
        except ImportError:
            pass
    return get_builtin(namespace)


def interactive(namespace):
    shell = get_shell(namespace)
    return shell()



